'''
Created on 04/03/2009

@author: eh01
'''
from im.ds import dsconstants, dsofactory
from im.ds.dsstub import DSStub
from im.event import eventconstants
from im.event.event import Event
from im.event.eventmanager import EventManager
import base64

def loginRequired(func):
    def wrapper(self, *args, **kw):
        dso = args[0]
        http_request = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST).get_literal()           
        try:
            (username, password) = getUserCredentials(http_request)
            ds_stub = DSStub()
            hub_username = ds_stub.get_hub_username()
            hub_password = ds_stub.get_hub_password();
            # passwords are stored as a md5 hash
            if username == hub_username and password == hub_password:
                func(self, *args, **kw)
            else:
                raise LoginException("username and password invalid")
        except LoginException, e:
            lock = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                        predicate=dsconstants.PREDICATE_LOCK).get_literal()
                        
            # create the http error dso
            dso = dsofactory.create_dso_for_http_error_handler(401, 
                                                         e.message, 
                                                         http_request, 
                                                         lock)
            event_type = eventconstants.HTTP_ERROR_EVENT_TYPE
            event = Event(event_type, dso)
            EventManager().add_event(event)
    return wrapper

def adminLoginRequired(func):
    def wrapper(self, *args, **kw):
        dso = args[0]
        http_request = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST).get_literal()           
        try:
            (username, password) = getUserCredentials(http_request)
            ds_stub = DSStub()
            hub_username = ds_stub.get_hub_username()
            hub_password = ds_stub.get_hub_password();
            # passwords are stored as a md5 hash
            if username == hub_username and password == hub_password:
                func(self, *args, **kw)
            else:
                raise LoginException("username and password invalid")
        except LoginException, e:
            lock = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                        predicate=dsconstants.PREDICATE_LOCK).get_literal()
                        
            # create the http error dso
            dso = dsofactory.create_dso_for_http_error_handler(401, 
                                                         e.message, 
                                                         http_request, 
                                                         lock)
            event_type = eventconstants.HTTP_ERROR_EVENT_TYPE
            event = Event(event_type, dso)
            EventManager().add_event(event)
    return wrapper

def getUserCredentials(request):
    """ returns the user credentials from the http header """
    try:
        # the http header with the credentials
        authorization = request.headers["Authorization"]
        scheme, basic_credentials = authorization.split()
        # check the scheme is 'Basic' and that the credentials are present
        if (scheme == 'Basic') and (basic_credentials is not None):
            # decode the username and password
            user_pass = base64.b64decode(basic_credentials)
            username, password = user_pass.split(':')
#            print "Username and password supplied"
            return (username, password)
        else:
            raise LoginException("Failed to get credentials")
    except Exception:
        raise LoginException("Failed to get credentials")
    
class LoginException(Exception):
    
    def __init__(self, message):
        Exception.__init__(self, message);